package com.weipt.config;

import com.weipt.security.UserDetailsServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityCustomizer;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.RememberMeServices;
import org.springframework.security.web.authentication.rememberme.TokenBasedRememberMeServices;

/**
 * @author weipt
 * @description 安全配置类
 * @date 2024/9/3 22:52
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig{

    @Autowired
    private UserDetailsServiceImpl userDetailsService;

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf().disable()
            .authorizeRequests()
                .mvcMatchers( "/handleLogin").permitAll() //此处添加的路径，会允许不走认证，但安全过滤器还是会进
                .anyRequest().authenticated()
            .and()
            .formLogin().loginPage("/loginPage.jsp").permitAll()//加上permitAll，意味着不用认证也可以访问登录页面，所以直接访问根目录的jsp文件，或者我们暴露一个controller也行
            .and()
            .logout()
                .logoutUrl("/logout") //拦截前端界面请求的url，比如jsp点击退出后，执行的请求url
                .logoutSuccessUrl("/loginPage.jsp") // 登出成功后的重定向URL
                .invalidateHttpSession(true) // 注销时无效化session
                .deleteCookies("JSESSIONID", "remember-me") // 删除cookie,删除后重新进入登录界面，还没有登录就有JSESSIONID，可能是临时的
                .clearAuthentication(true) // 清除服务端认证信息信息
                .permitAll(); // 允许所有人访问登出URL
                //访问首页，只要进入了安全，就会生成一个anonymousUser省份的jsessionid
                //SessionManagementFilter过滤器中有判断!this.trustResolver.isAnonymous(authentication)
        // .rememberMe().rememberMeServices(rememberMeServices);  //自定义rememberMeServices，并加入了@Bean，此处就不需要配置
        return http.build();
    }

    @Bean
    public WebSecurityCustomizer webSecurityCustomizer() {
        return (web) -> web. ignoring().antMatchers("/static/**","/favicon.ico");
    }
    /**
     * 注册rememberMeServices，之所以弄成bean，因为要在登录成功后，调用loginSucces方法，返回前端remember-me信息，然后浏览器存储
     * @return
     */
    @Bean
    public RememberMeServices rememberMeServices(){
        TokenBasedRememberMeServices rememberMeServices = new TokenBasedRememberMeServices("weipt", userDetailsService);
        rememberMeServices.setUseSecureCookie(true);
        return rememberMeServices;
    }
}